package org.gaaidou.ptarmigan.springboot.data.jpa;

import com.alibaba.druid.pool.DruidDataSource;
import org.gaaidou.ptarmigan.springboot.core.common.FormatUtil;
import org.gaaidou.ptarmigan.springboot.core.spring.PropsUtil;
import org.gaaidou.ptarmigan.springboot.data.jpa.datasource.RoutingDataSource;
import org.gaaidou.ptarmigan.springboot.data.jpa.datasource.RoutingDataSourceProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.env.Environment;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import java.util.Map;
import java.util.Properties;
import java.util.stream.Collectors;


@Configuration
@ComponentScan("org.gaaidou.ptarmigan.springboot.data.jpa")
@EnableTransactionManagement
public class JpaConfig {

    @Bean
    @Primary
    public RoutingDataSource dataSource(Environment environment) {
        RoutingDataSourceProperties routingDataSourceProperties = PropsUtil.getConfigByEnv(environment, "spring.datasource", RoutingDataSourceProperties.class);

        Properties props = new Properties();
        routingDataSourceProperties.getDruid()
                .forEach((k, v) -> props.put(String.format("druid.%s", FormatUtil.hyphenToHump(k.toString())), v));
        RoutingDataSource routingDataSource = new RoutingDataSource();
        Map<Object, Object> targetDataSources = routingDataSourceProperties.getNodes().entrySet()
                .stream()
                .collect(Collectors.toMap(
                        Map.Entry::getKey,
                        v -> {
                            var ds = v.getValue();
                            var k = v.getKey();
                            DruidDataSource dataSource = new DruidDataSource();
                            dataSource.setUrl(ds.getUrl());
                            dataSource.setUsername(ds.getUsername());
                            dataSource.setPassword(ds.getPassword());
                            dataSource.setDriverClassName(ds.getDriverClassName());
                            dataSource.configFromPropeties(props);
                            if (null == routingDataSource.getResolvedDefaultDataSource()) {
                                routingDataSource.setDefaultTargetDataSource(dataSource);
                            }
                            routingDataSource.multipleKey(k);
                            return dataSource;
                        }));

        routingDataSource.setTargetDataSources(targetDataSources);
        return routingDataSource;
    }
}
